/*
 *    Copyright (c) 2018-2025, exsecs All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: exsecs
 */

package com.excesys.exsecs.linkage.task;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.excesys.exsecs.access.constant.RedisConstant;
import com.excesys.exsecs.access.entity.AccessDeviceInfo;
import com.excesys.exsecs.access.entity.AccessThingModel;
import com.excesys.exsecs.access.service.AccessDeviceInfoService;
import com.excesys.exsecs.access.service.AccessThingModelService;
import com.excesys.exsecs.access.vo.ThingInvokeVO;
import com.excesys.exsecs.admin.api.entity.SysDictItem;
import com.excesys.exsecs.admin.api.vo.UserVO;
import com.excesys.exsecs.admin.service.SysDictItemService;
import com.excesys.exsecs.admin.service.SysUserService;
import com.excesys.exsecs.alarm.entity.AlarmRecord;
import com.excesys.exsecs.alarm.entity.AlarmTypeConf;
import com.excesys.exsecs.alarm.service.AlarmRecordService;
import com.excesys.exsecs.alarm.service.AlarmTypeConfService;
import com.excesys.exsecs.common.security.util.SecurityUtils;
import com.excesys.exsecs.linkage.alarm.TencentEnterpriseEmailSender;
import com.excesys.exsecs.linkage.constants.exsecsQuartzEnum;
import com.excesys.exsecs.linkage.entity.*;
import com.excesys.exsecs.linkage.mapper.SceneExecuteActionMapper;
import com.excesys.exsecs.linkage.mapper.SceneExecuteConditionsMapper;
import com.excesys.exsecs.linkage.mapper.SceneLinkageMapper;
import com.excesys.exsecs.linkage.service.SceneLinkageLogService;
import com.excesys.exsecs.linkage.service.SceneLinkageService;
import com.excesys.exsecs.linkage.vo.ConditionVo;
import com.excesys.exsecs.linkage.vo.SceneLinkageVO;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author 郑健楠
 */
@Slf4j
@Component("scene")
public class SceneLinkageTask {
	@Autowired
	private SceneLinkageMapper sceneLinkageMapper;
	@Autowired
	private SceneExecuteActionMapper sceneExecuteActionMapper;

	@Autowired
	private AccessThingModelService accessThingModelService;
	@Autowired
	private SceneLinkageService sceneLinkageService;
	@Autowired
	private StringRedisTemplate redisTemplate;

	@Autowired
	private AccessDeviceInfoService accessDeviceInfoService;
	@Autowired
	private AlarmTypeConfService alarmTypeConfService;
	@Autowired
	private SysDictItemService sysDictItemService;
	@Autowired
	private AlarmRecordService alarmRecordService;
	@Autowired
	private SceneLinkageLogService sceneLinkageLogService;

	@Autowired
	private TencentEnterpriseEmailSender sender;

	@Autowired
	private SysUserService userService;

	/**
	 * 测试Spring Bean的演示方法
	 */
	@SneakyThrows
	public String demoMethod(String para) {
		log.info("测试于:{}，输入参数{}", LocalDateTime.now(), para);
		log.info("开始处理规则引擎定时触发任务。。。。。");
		boolean sign = false;
		boolean sign1 = false;
		boolean timeFlag = false;
		boolean timeFlag1 = false;
		Boolean conditionFlag = false;
		// 获取当前日期
		LocalDate today = LocalDate.now();
		// 获取星期几
		String dayOfWeek = today.getDayOfWeek().getValue() + "";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		// 格式化日期时间
		String formattedDate = sdf.format(new Date());
		//获取当前时分秒用作下面判断是否在触发器时间内
		LocalDateTime dateTime = LocalDateTime.parse(formattedDate, formatter);
		LocalTime time = dateTime.toLocalTime();
		String Linked = "";
		//获取启动状态的规则场景
		List<SceneLinkage> sceneLinkageList = sceneLinkageMapper.getSceneLinkageList(1,1);
		for (SceneLinkage sceneLinkage : sceneLinkageList) {
			log.info("遍历获取启动的规则。。。。。" + sceneLinkage);
			List<SceneTrigger> triggers = new ArrayList<>();
			SceneLinkageVO sceneLinkageVO = sceneLinkageService.getByLinkageId(sceneLinkage.getLinkageId());
			//判断是否为定时触发
			List<SceneExecuteAction> executeActionList = sceneLinkageVO.getSceneExecuteActionList();
			List<SceneTrigger> triggerList = sceneLinkageVO.getSceneTriggerList();
			List<SceneExecuteConditions> sceneExecuteConditionsList = sceneLinkageVO.getSceneExecuteConditionsList();
			if (triggerList.size() == 0 && sceneExecuteConditionsList.size() == 0) {
				Boolean status = true;
				for (SceneExecuteAction sceneExecuteAction : executeActionList) {
					Linked = sceneExecuteAction.getLinkageId();
					ThingInvokeVO thingInvokeVO = new ThingInvokeVO();
					thingInvokeVO.setService(sceneExecuteAction.getIdentifier());
					thingInvokeVO.setTimestamp(System.currentTimeMillis());
					//执行动作模式 （1设备输出  2关联告警 3消息发送）
					if (sceneExecuteAction.getTriggerMode() == 1) {
						JSONObject jsonObject = new JSONObject();
						for (SceneExecuteActionModel model : sceneExecuteAction.getSceneExecuteActionModelList()) {
							String[] uniiNos = sceneExecuteAction.getUnitNo().split(",");
							for (String unitNO : uniiNos) {
								thingInvokeVO.setUnitNo(unitNO);
								// 如果设备离线，则直接返回离线信息
								AccessDeviceInfo device = accessDeviceInfoService.getOne(Wrappers.<AccessDeviceInfo>lambdaQuery().eq(AccessDeviceInfo::getUnitNo, unitNO));
								if (device.getOnlineStatus() != 0) {
									if ("int32".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
									} else if ("float".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), Float.valueOf(model.getValue()));
									} else if ("bool".equals(model.getType())) {
										if ("1".equals(model.getValue())) {
											jsonObject.put(model.getCircuitId(), Boolean.TRUE);
										} else {
											jsonObject.put(model.getCircuitId(), Boolean.FALSE);
										}
									} else if ("enum".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
									} else if ("text".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), String.valueOf(model.getValue()));
									}
								}
							}
						}
						thingInvokeVO.setArgs(jsonObject);
						if (ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())) {
							Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime()) * 1000);
						}
						ThingInvokeVO thingInvokeVO1 = accessDeviceInfoService.invoke(thingInvokeVO);
						System.out.println("thingInvokeVO1:" + thingInvokeVO1);
					} else if (sceneExecuteAction.getTriggerMode() == 2) {
						//根据告警类型走
						AlarmTypeConf alarmTypeConf = alarmTypeConfService.getTypeByCode(sceneExecuteAction.getAlarmId());
						SysDictItem sysDictItem = sysDictItemService.getById(sceneExecuteAction.getAlarmInfo());
						AlarmRecord alarmRecord = new AlarmRecord();
						alarmRecord.setAlarmContent(sysDictItem.getLabel());
						//alarmRecord.setUnitNo(sceneTrigger.getUnitNo());
						alarmRecord.setAlarmTypeCode(alarmTypeConf.getTypeCode());
						alarmRecord.setAlarmLevel(Integer.valueOf(alarmTypeConf.getLevel()));
						alarmRecord.setSender(alarmTypeConf.getSender());
						//alarmRecord.setConfigType(sceneTrigger.getConfigType());
						//alarmRecord.setHappenTime(sceneTrigger.getTimeStamp());
						//alarmRecord.setUnit(sceneTrigger.getUnit());
						alarmRecord.setCreateBy("system");
						alarmRecord.setUpdateBy("system");
//						if (sceneTrigger.getConfigType() != 3 || sceneTrigger.getConfigType() != 6) {
//							alarmRecord.setFixedValue(sceneTrigger.getFixedValue());
//							alarmRecord.setAlarmValue(sceneTrigger.getVal().get("nowValue") + "");
//						} else {
//							alarmRecord.setLowerValue(sceneTrigger.getLowerValue());
//							alarmRecord.setUpperValue(sceneTrigger.getUpperValue());
//						}
						status = alarmRecordService.saveRecord(alarmRecord);
					} else if (sceneExecuteAction.getTriggerMode() == 3) {

					}
				}
				SceneLinkageLog sceneLinkageLog = new SceneLinkageLog();
				sceneLinkageLog.setLinkageId(Linked);
				sceneLinkageLog.setSceneName(sceneLinkageVO.getSceneName());
				sceneLinkageLog.setHappenTime(LocalDateTime.now());
				sceneLinkageLog.setInfo("设备触发");
				if (!status) {
					sceneLinkageLog.setStatus(0);
					sceneLinkageLog.setRemarks("执行动作失败");
				} else {
					sceneLinkageLog.setStatus(1);
					sceneLinkageLog.setRemarks("执行动作成功");
				}
				log.info("设备触发打印日志打印日志条件：sceneLinkageLog" + sceneLinkageLog);
				sceneLinkageLogService.save(sceneLinkageLog);
				break;
			}
			if(triggerList.size()>0){
				for (SceneTrigger tirgger : triggerList) {
					Linked = tirgger.getLinkageId();
					//触发器模式 （1设备  2 定时）
					if (tirgger.getTriggerMode() == 1) {
						if (ObjectUtil.isNotEmpty(tirgger.getUnitNo())) {
							String[] unitNos = tirgger.getUnitNo().split(",");
							for (String unitNo : unitNos) {
								Object objData = redisTemplate.opsForHash().get(RedisConstant.REPORT_LIST_KEY, unitNo);
								JSONObject jsonObject = new JSONObject(objData);
								if ("online".equals(tirgger.getChannelNo())) {
									String online = jsonObject.get("online") + "";
									if (online.equals(tirgger.getFixedValue())) {
										if ("1".equals(online)) {
											sign = true;
											break;
										}
									} else if ("offonline".equals(tirgger.getChannelNo())) {
										if ("0".equals(online)) {
											sign = true;
											break;
										}
									}
								}
								JSONArray jsonArray = getJson(unitNo);
								if (ObjectUtil.isNotEmpty(jsonArray)) {
									for (int i = 0; i < jsonArray.size(); i++) {
										JSONObject json1 = new JSONObject(jsonArray.get(i));
										if (json1.get("identifier").equals(tirgger.getChannelNo())) {
											JSONObject json2 = new JSONObject(json1.get("dataType"));
											if (ObjectUtil.isNotEmpty(json2.get("type"))) {
												if (ObjectUtil.isNotEmpty(json2.get("type"))) {
													if (ObjectUtil.isNotEmpty(objData)) {
														Map map = (Map) jsonObject.get("data");
														JSONObject jso = new JSONObject();
														jso.set("nowValue", map.get(tirgger.getChannelNo()) + "");
														if ("int32".equals(json2.get("type"))) {
															Integer nowValue = Integer.valueOf(map.get(tirgger.getChannelNo()) + "");
															//0-> 1-< 2-= 3-范围值
															if (tirgger.getConfigType() != 3) {
																Integer fixedValue = Integer.valueOf(tirgger.getFixedValue() + "");
																if (tirgger.getConfigType() == 0) {
																	if (nowValue.compareTo(fixedValue) > 0) {
																		sign = true;
																		tirgger.setUnitNo(unitNo);
																		tirgger.setVal(jso);
																		triggers.add(tirgger);
																		break;
																	}
																} else if (tirgger.getConfigType() == 1) {
																	if (nowValue.compareTo(fixedValue) < 0) {
																		sign = true;
																		tirgger.setUnitNo(unitNo);
																		tirgger.setVal(jso);
																		triggers.add(tirgger);
																		break;
																	}
																} else if (tirgger.getConfigType() == 2) {
																	if (nowValue.compareTo(fixedValue) == 0) {
																		sign = true;
																		tirgger.setUnitNo(unitNo);
																		tirgger.setVal(jso);
																		triggers.add(tirgger);
																		break;
																	}
																} else if (tirgger.getConfigType() == 4) {
																	if (fixedValue >= nowValue) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	}
																} else if (tirgger.getConfigType() == 5) {
																	if (nowValue <= fixedValue) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	}
																}
															} else {
																Integer leftValue = Integer.valueOf(tirgger.getLowerValue());
																Integer rightValue = Integer.valueOf(tirgger.getUpperValue());
																if (tirgger.getConfigType() == 3) {
																	if (leftValue.compareTo(nowValue) < 0 && rightValue.compareTo(nowValue) > 0) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	}
																} else if (tirgger.getConfigType() == 6) {
																	if (nowValue < leftValue && nowValue > rightValue) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	}
																}
															}
														} else if ("float".equals(json2.get("type"))) {
															Float nowValue = Float.valueOf(map.get(tirgger.getChannelNo()) + "");
															//0-> 1-< 2-= 3-范围值
															if (tirgger.getConfigType() != 3) {
																Float fixedValue = Float.valueOf(tirgger.getFixedValue() + "");
																if (tirgger.getConfigType() == 0) {
																	if (nowValue.compareTo(fixedValue) > 0) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	}
																} else if (tirgger.getConfigType() == 1) {
																	if (nowValue.compareTo(fixedValue) < 0) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	}
																} else if (tirgger.getConfigType() == 2) {
																	if (nowValue.compareTo(fixedValue) == 0) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	}
																} else if (tirgger.getConfigType() == 4) {
																	if (fixedValue >= nowValue) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	}
																} else if (tirgger.getConfigType() == 5) {
																	if (nowValue <= fixedValue) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	}
																}
															} else {
																Float leftValue = Float.valueOf(tirgger.getLowerValue());
																Float rightValue = Float.valueOf(tirgger.getUpperValue());
																if (tirgger.getConfigType() == 3) {
																	if (leftValue < nowValue && rightValue > nowValue) {
																		sign = true;
																		tirgger.setVal(jso);
																		tirgger.setUnitNo(unitNo);
																		triggers.add(tirgger);
																		break;
																	} else if (tirgger.getConfigType() == 6) {
																		if (nowValue < leftValue && nowValue > rightValue) {
																			sign = true;
																			tirgger.setVal(jso);
																			tirgger.setUnitNo(unitNo);
																			triggers.add(tirgger);
																			break;
																		}
																	}
																}
															}
														}
													} else {
														break;
													}
												} else {
													break;
												}
											}
										}
									}

								}
							}
						}

					} else if (tirgger.getTriggerMode() == 2) {
						Linked = tirgger.getLinkageId();
						log.info("规则引擎走的定时触发。。。。。");
						List<SceneTriggerTime> sceneTriggerTimes = tirgger.getSpecialDateList();
						//判断是否在设置的星期内
						boolean week = tirgger.getWeek().contains(dayOfWeek);
						boolean value = sceneTriggerTimes.stream().anyMatch(sceneTriggerTime -> today.toString().equals(sceneTriggerTime.getSpecialDate()));
						if (value || week) {
							LocalTime startTime = LocalTime.parse(tirgger.getSetTime());
							timeFlag = !time.isBefore(startTime);
						}
					}
					//设备触发器或时间触发器满足一个跳出循环执行下一步 执行条件
					if (sign || timeFlag) {
						int j = 0;
						JSONObject object = new JSONObject();
						//判断有无重复触发次数&触发时间间隔
						if (ObjectUtil.isNotEmpty(tirgger.getTriggerNumber())) {
							if (ObjectUtil.isNotEmpty(tirgger.getIntervalTime())) {
								Object objData = redisTemplate.opsForHash().get("linked_list", tirgger.getLinkageId());
								if (ObjectUtil.isNotEmpty(objData)) {
									JSONObject jsonObject = new JSONObject(objData);
									j = Integer.valueOf(jsonObject.get("num") + "");
								}
								if (j < tirgger.getTriggerNumber() || j == 0) {
									log.info("规则引擎走的触发少于触发次数。。。。。");
									object.set("num", j + 1);
									object.set("time", LocalDateTime.now());
									redisTemplate.opsForHash().put("linked_list", tirgger.getLinkageId(), object + "");
								} else {
									sign1 = false;
									break;
								}
							}
						}
						sign1 = true;
						if (ObjectUtil.isNotEmpty(tirgger.getIntervalTime())) {
							Thread.sleep(Integer.valueOf(tirgger.getIntervalTime()) * 1000);
						}
					} else {
						SceneLinkageLog sceneLinkageLog = new SceneLinkageLog();
						sceneLinkageLog.setLinkageId(sceneLinkageVO.getLinkageId());
						sceneLinkageLog.setSceneName(sceneLinkageVO.getSceneName());
						sceneLinkageLog.setStatus(0);
						sceneLinkageLog.setHappenTime(LocalDateTime.now());
						sceneLinkageLog.setInfo("定时触发");
						sceneLinkageLog.setRemarks("触发器校验失败");
						sceneLinkageLogService.save(sceneLinkageLog);
					}
				}
			}

			//执行动作
			boolean status = false;
			List<SceneExecuteConditions> secList = new ArrayList<>();
			if(sceneExecuteConditionsList.size()>0){
				log.info("规则引擎走执行动作。。。。。");
				for (SceneExecuteConditions sceneExecuteCondition : sceneExecuteConditionsList) {
					Linked = sceneExecuteCondition.getLinkageId();
					//执行条件（ 0: 全部条件  1: 任意一个条件）
					if (sceneExecuteCondition.getConditions() == 1) {
						//判断是设备还是时间  1-设备 2-时间
						if (sceneExecuteCondition.getTriggerMode() == 1) {
							if (ObjectUtil.isNotEmpty(sceneExecuteCondition.getUnitNo())) {
								String[] uniiNos = sceneExecuteCondition.getUnitNo().split(",");
								for (String unitNo : uniiNos) {
									SceneExecuteConditions sceneExecuteCondition1 = new SceneExecuteConditions();
									BeanUtils.copyProperties(sceneExecuteCondition, sceneExecuteCondition1);
									sceneExecuteCondition1.setUnitNo(unitNo);
									Object objData = redisTemplate.opsForHash().get(RedisConstant.REPORT_LIST_KEY, unitNo);
									if (ObjectUtil.isNotEmpty(objData)) {
										JSONObject jsonObject = new JSONObject(objData);
										Map map = (Map) jsonObject.get("data");
										JSONObject jso = new JSONObject();
										jso.set("nowValue", map.get(sceneExecuteCondition.getChannelNo()) + "");
										if ("online".equals(sceneExecuteCondition.getChannelNo())) {
											String online = jsonObject.get("online") + "";
											if (online.equals(sceneExecuteCondition.getFixedValue())) {
												conditionFlag = true;
												break;
											}
										}
										JSONArray jsonArray = getJson(unitNo);
										if (ObjectUtil.isNotEmpty(jsonArray)) {
											for (int i = 0; i < jsonArray.size(); i++) {
												JSONObject json1 = new JSONObject(jsonArray.get(i));
												if (json1.get("identifier").equals(sceneExecuteCondition.getChannelNo())) {
													JSONObject json2 = new JSONObject(json1.get("dataType"));
													if (ObjectUtil.isNotEmpty(json2.get("type"))) {
														if (ObjectUtil.isNotEmpty(json2.get("type"))) {
															if (ObjectUtil.isNotEmpty(objData)) {
																if (getBoolean(json2.get("type"), sceneExecuteCondition, map)) {
																	conditionFlag = true;
																	if (sceneExecuteCondition.getConfigType() != 3 || sceneExecuteCondition.getConfigType() != 6) {
																		sceneExecuteCondition1.setVal(jso);
																	}
																	secList.add(sceneExecuteCondition1);
																	execute(triggers, secList, sceneLinkageVO);
																	status = true;
																	break;
																}
															} else {
																continue;
															}
														} else {
															continue;
														}
													}
												}
											}

										}
									}
									if (status) {
										break;
									}
								}
							}


						} else if (sceneExecuteCondition.getTriggerMode() == 2) {
							List<SceneExecuteConditions> secs = new ArrayList<>();
							if ("1".equals(sceneExecuteCondition.getTimeScope())) {
								LocalDateTime start1Time = LocalDateTime.parse(sceneExecuteCondition.getStartTime() + "", formatter);
								LocalDateTime end1Time = LocalDateTime.parse(sceneExecuteCondition.getEndTime() + "", formatter);
								// 获取当前时间
								LocalDateTime now = LocalDateTime.now();
								// 判断当前时间是否在时间范围内
								if (!now.isBefore(start1Time) && !now.isAfter(end1Time)) {
									execute(triggers, secs, sceneLinkageVO);
								}
							} else {
								execute(triggers, secs, sceneLinkageVO);
							}
						}
					} else if (sceneExecuteCondition.getConditions() == 0) {
						log.info("规则引擎走全部执行动作。。。。。");
						List<Boolean> booleanList = new ArrayList<>();
						//判断是设备还是时间  1-设备 2-时间
						if (sceneExecuteCondition.getTriggerMode() == 1) {
							if (ObjectUtil.isNotEmpty(sceneExecuteCondition.getUnitNo())) {
								String[] uniiNos = sceneExecuteCondition.getUnitNo().split(",");
								for (String unitNo : uniiNos) {
									log.info("规则引擎走全部执行动作遍历unitno。。。。。" + unitNo);
									SceneExecuteConditions sceneExecuteCondition1 = new SceneExecuteConditions();
									BeanUtils.copyProperties(sceneExecuteCondition, sceneExecuteCondition1);
									sceneExecuteCondition1.setUnitNo(unitNo);
									Object objData = redisTemplate.opsForHash().get(RedisConstant.REPORT_LIST_KEY, unitNo);
									log.info("规则引擎走全部执行动作objData。。。。。" + objData);
									if (ObjectUtil.isNotEmpty(objData)) {
										JSONObject jsonObject = new JSONObject(objData);
										Map map = (Map) jsonObject.get("data");
										log.info("规则引擎走全部执行动作map。。。。。" + map);
										JSONObject jso = new JSONObject();
										jso.set("nowValue", map.get(sceneExecuteCondition.getChannelNo()) + "");
										JSONArray jsonArray = getJson(unitNo);
										if ("online".equals(sceneExecuteCondition.getChannelNo())) {
											String online = jsonObject.get("online") + "";
											if (online.equals(sceneExecuteCondition.getFixedValue())) {
												booleanList.add(true);
											} else {
												booleanList.add(false);
											}
										}
										if (ObjectUtil.isNotEmpty(jsonArray)) {
											log.info("规则引擎走全部执行动作jsonArray。。。。。" + jsonArray);
											for (int i = 0; i < jsonArray.size(); i++) {
												JSONObject json1 = new JSONObject(jsonArray.get(i));
												if (json1.get("identifier").equals(sceneExecuteCondition.getChannelNo())) {
													JSONObject json2 = new JSONObject(json1.get("dataType"));
													if (ObjectUtil.isNotEmpty(json2.get("type"))) {
														if (ObjectUtil.isNotEmpty(json2.get("type"))) {
															if (ObjectUtil.isNotEmpty(objData)) {
																if (getBoolean(json2.get("type"), sceneExecuteCondition, map)) {
																	log.info("规则引擎走全部执行动作true。。。。。");
																	booleanList.add(true);
																	if (sceneExecuteCondition.getConfigType() != 3 || sceneExecuteCondition.getConfigType() != 6) {
																		sceneExecuteCondition1.setVal(jso);
																	}
																	secList.add(sceneExecuteCondition1);
																	break;
																} else {
																	log.info("规则引擎走全部执行动作false。。。。。");
																	booleanList.add(false);
																	break;
																}
															}
														}
													}
												}
											}
										}

									}
								}
							}

						} else if (sceneExecuteCondition.getTriggerMode() == 2) {
							if ("1".equals(sceneExecuteCondition.getTimeScope())) {
								LocalDateTime start1Time = LocalDateTime.parse(sceneExecuteCondition.getStartTime(), formatter);
								LocalDateTime end1Time = LocalDateTime.parse(sceneExecuteCondition.getEndTime(), formatter);
								// 获取当前时间
								LocalDateTime now = LocalDateTime.now();
								// 判断当前时间是否在时间范围内
								if (!now.isBefore(start1Time) && !now.isAfter(end1Time)) {
									timeFlag1 = true;
								}
							} else {
								timeFlag1 = true;
							}
						}
						if (sceneExecuteConditionsList.indexOf(sceneExecuteCondition) == sceneExecuteConditionsList.size() - 1) {
							log.info("规则引擎走全部执行动作最后一个。。。。。");
							if (!booleanList.contains(false)) {
								conditionFlag = true;
							}
							log.info("规则引擎走全部执行动作booleanList。。。。。" + booleanList);
							booleanList.clear();
							if (conditionFlag || timeFlag1) {
								log.info("规则引擎走到执行动作。。。。。");
								execute(triggers, secList, sceneLinkageVO);
							} else {
								SceneLinkageLog sceneLinkageLog = new SceneLinkageLog();
								sceneLinkageLog.setLinkageId(sceneLinkageVO.getLinkageId());
								sceneLinkageLog.setSceneName(sceneLinkageVO.getSceneName());
								sceneLinkageLog.setStatus(0);
								sceneLinkageLog.setHappenTime(LocalDateTime.now());
								sceneLinkageLog.setInfo("定时触发");
								sceneLinkageLog.setRemarks("执行条件校验失败");
								sceneLinkageLogService.save(sceneLinkageLog);
							}
						}

					}
				}
			}else{
				execute(triggers, secList, sceneLinkageVO);
			}

		}
		log.info("结束处理规则引擎定时触发任务。。。。。");
		return exsecsQuartzEnum.JOB_LOG_STATUS_SUCCESS.getType();
	}

	private void execute(List<SceneTrigger> triggers, List<SceneExecuteConditions> secList, SceneLinkageVO sceneLinkageVO) throws Exception {
		Boolean status = true;
		Boolean status1 =true;
		String Linked = "";
		List<Boolean> booleanList = new ArrayList<>();
		List<String> unitNos = new ArrayList<>();
		String alarmId = "";
		if (triggers.size() > 0) {
			for (SceneTrigger sceneTrigger : triggers) {
				Linked = sceneTrigger.getLinkageId();
				log.info("规则引擎走到执行动作触发器。。。。。" + sceneTrigger);
				ConditionVo conditionVo = new ConditionVo();
				conditionVo.setLinkageId(sceneTrigger.getLinkageId());
				List<SceneExecuteAction> sceneExecuteActions = sceneExecuteActionMapper.getInfoById(conditionVo);
				for (SceneExecuteAction sceneExecuteAction : sceneExecuteActions) {
					ThingInvokeVO thingInvokeVO = new ThingInvokeVO();
					thingInvokeVO.setService(sceneExecuteAction.getIdentifier());
					thingInvokeVO.setTimestamp(System.currentTimeMillis());
					//执行动作模式 （1设备输出  2关联告警 3消息发送）
					if (sceneExecuteAction.getTriggerMode() == 1) {
						JSONObject jsonObject = new JSONObject();
						for (SceneExecuteActionModel model : sceneExecuteAction.getSceneExecuteActionModelList()) {
							String[] uniiNos = sceneExecuteAction.getUnitNo().split(",");
							for (String unitNO : uniiNos) {
								thingInvokeVO.setUnitNo(unitNO);
								// 如果设备离线，则直接返回离线信息
								AccessDeviceInfo device = accessDeviceInfoService.getOne(Wrappers.<AccessDeviceInfo>lambdaQuery().eq(AccessDeviceInfo::getUnitNo, unitNO));
								if (device.getOnlineStatus() != 0) {
									if ("int32".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
									} else if ("float".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), Float.valueOf(model.getValue()));
									} else if ("bool".equals(model.getType())) {
										if ("1".equals(model.getValue())) {
											jsonObject.put(model.getCircuitId(), Boolean.TRUE);
										} else {
											jsonObject.put(model.getCircuitId(), Boolean.FALSE);
										}
									} else if ("enum".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
									} else if ("text".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), String.valueOf(model.getValue()));
									}
								}
							}
						}
						thingInvokeVO.setArgs(jsonObject);
						if (ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())) {
							Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime()) * 1000);
						}
						ThingInvokeVO thingInvokeVO1 = accessDeviceInfoService.invoke(thingInvokeVO);
						System.out.println("thingInvokeVO1:" + thingInvokeVO1);
					} else if (sceneExecuteAction.getTriggerMode() == 2) {
						alarmId = sceneExecuteAction.getAlarmId();
						unitNos.add(sceneTrigger.getUnitNo());
						//根据告警类型走
						AlarmTypeConf alarmTypeConf = alarmTypeConfService.getTypeByCode(sceneExecuteAction.getAlarmId());
						SysDictItem sysDictItem = sysDictItemService.getById(sceneExecuteAction.getAlarmInfo());
						AlarmRecord alarmRecord = new AlarmRecord();
						alarmRecord.setAlarmContent(sysDictItem.getLabel());
						alarmRecord.setUnitNo(sceneTrigger.getUnitNo());
						alarmRecord.setAlarmTypeCode(alarmTypeConf.getTypeCode());
						alarmRecord.setAlarmLevel(Integer.valueOf(alarmTypeConf.getLevel()));
						alarmRecord.setSender(alarmTypeConf.getSender());
						alarmRecord.setConfigType(sceneTrigger.getConfigType());
						alarmRecord.setHappenTime(sceneTrigger.getTimeStamp());
						alarmRecord.setUnit(sceneTrigger.getUnit());
						alarmRecord.setHappenTime(LocalDateTime.now());
						alarmRecord.setCreateBy("system");
						alarmRecord.setUpdateBy("system");
						if (sceneTrigger.getConfigType() != 3 || sceneTrigger.getConfigType() != 6) {
							alarmRecord.setAlarmValue(sceneTrigger.getVal().get("nowValue") + "");
							alarmRecord.setFixedValue(sceneTrigger.getFixedValue());
						} else {
							alarmRecord.setLowerValue(sceneTrigger.getLowerValue());
							alarmRecord.setUpperValue(sceneTrigger.getUpperValue());
						}
						if (ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())) {
							Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime()) * 1000);
						}
						 status = alarmRecordService.saveRecord(alarmRecord);
					}
				}
			}
		}
		if (secList.size() > 0) {
			for (SceneExecuteConditions sec : secList) {
				log.info("规则引擎走到执行条件。。。。。" + sec);
				ConditionVo conditionVo = new ConditionVo();
				conditionVo.setLinkageId(sec.getLinkageId());
				List<SceneExecuteAction> sceneExecuteActions = sceneExecuteActionMapper.getInfoById(conditionVo);
				//根据执行条件任意一个或全部判断执行下一步
				for (SceneExecuteAction sceneExecuteAction : sceneExecuteActions) {
					Linked = sceneExecuteAction.getLinkageId();
					ThingInvokeVO thingInvokeVO = new ThingInvokeVO();
					thingInvokeVO.setService(sceneExecuteAction.getIdentifier());
					thingInvokeVO.setTimestamp(System.currentTimeMillis());
					//执行动作模式 （1设备输出  2关联告警 3消息发送）
					if (sceneExecuteAction.getTriggerMode() == 1) {
						JSONObject jsonObject = new JSONObject();
						for (SceneExecuteActionModel model : sceneExecuteAction.getSceneExecuteActionModelList()) {
							String[] uniiNos = sceneExecuteAction.getUnitNo().split(",");
							for (String unitNO : uniiNos) {
								thingInvokeVO.setUnitNo(unitNO);
								// 如果设备离线，则直接返回离线信息
								AccessDeviceInfo device = accessDeviceInfoService.getOne(Wrappers.<AccessDeviceInfo>lambdaQuery().eq(AccessDeviceInfo::getUnitNo, unitNO));
								if (device.getOnlineStatus() != 0) {
									if ("int32".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
									} else if ("float".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), Float.valueOf(model.getValue()));
									} else if ("bool".equals(model.getType())) {
										if ("1".equals(model.getValue())) {
											jsonObject.put(model.getCircuitId(), Boolean.TRUE);
										} else {
											jsonObject.put(model.getCircuitId(), Boolean.FALSE);
										}
									} else if ("enum".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), Integer.valueOf(model.getValue()));
									} else if ("text".equals(model.getType())) {
										jsonObject.put(model.getCircuitId(), String.valueOf(model.getValue()));
									}
								}
							}
						}
						thingInvokeVO.setArgs(jsonObject);
						if (ObjectUtil.isNotEmpty(sceneExecuteAction.getDelayTime())) {
							Thread.sleep(Integer.valueOf(sceneExecuteAction.getDelayTime()) * 1000);
						}
						ThingInvokeVO thingInvokeVO1 = accessDeviceInfoService.invoke(thingInvokeVO);
						System.out.println("thingInvokeVO1:" + thingInvokeVO1);
					} else if (sceneExecuteAction.getTriggerMode() == 2) {
						alarmId = sceneExecuteAction.getAlarmId();
						unitNos.add(sec.getUnitNo());
						//根据告警类型走
						AlarmTypeConf alarmTypeConf = alarmTypeConfService.getTypeByCode(sceneExecuteAction.getAlarmId());
						SysDictItem sysDictItem = sysDictItemService.getById(sceneExecuteAction.getAlarmInfo());
						AlarmRecord alarmRecord = new AlarmRecord();
						alarmRecord.setAlarmContent(sysDictItem.getLabel());
						alarmRecord.setUnitNo(sec.getUnitNo());
						alarmRecord.setAlarmTypeCode(alarmTypeConf.getTypeCode());
						alarmRecord.setAlarmLevel(Integer.valueOf(alarmTypeConf.getLevel()));
						alarmRecord.setSender(alarmTypeConf.getSender());
						alarmRecord.setConfigType(sec.getConfigType());
						alarmRecord.setHappenTime(sec.getTimeStamp());
						alarmRecord.setUnit(sec.getUnit());
						alarmRecord.setCreateBy("system");
						alarmRecord.setUpdateBy("system");
						alarmRecord.setHappenTime(LocalDateTime.now());
						if (sec.getConfigType() != 3 || sec.getConfigType() != 6) {
							alarmRecord.setAlarmValue(sec.getVal().get("nowValue") + "");
							alarmRecord.setFixedValue(sec.getFixedValue());
						} else {
							alarmRecord.setLowerValue(sec.getLowerValue());
							alarmRecord.setUpperValue(sec.getUpperValue());
						}
						 status1 = alarmRecordService.saveRecord(alarmRecord);
						booleanList.add(status1);
					}
				}
			}
		}
		SceneLinkageLog sceneLinkageLog = new SceneLinkageLog();
		sceneLinkageLog.setLinkageId(sceneLinkageVO.getSceneExecuteActionList().get(0).getLinkageId());
		sceneLinkageLog.setSceneName(sceneLinkageVO.getSceneName());
		sceneLinkageLog.setHappenTime(LocalDateTime.now());
		sceneLinkageLog.setInfo("定时触发");
		System.out.println("booleanList:"+booleanList);
		if (booleanList.contains(false) || !status) {
			sceneLinkageLog.setStatus(0);
			if(!status) {
				sceneLinkageLog.setRemarks("触发器去执行动作失败");
			}
			if(booleanList.contains(false)){
				sceneLinkageLog.setRemarks("执行条件去执行动作失败");
			}
			if(!status && booleanList.contains(false)){
				sceneLinkageLog.setRemarks("触发器和执行条件去执行动作都失败");
			}
		}else{
			sceneLinkageLog.setStatus(1);
			sceneLinkageLog.setRemarks("执行动作成功");
		}
		log.info("定时触发打印日志打印日志条件：sceneLinkageLog"+sceneLinkageLog);
		sceneLinkageLogService.save(sceneLinkageLog);
		//推送告警
		String body = "该设备出现异常，请及时处理（定时触发）!";
		String head = "";
		HashSet<String> set = new HashSet<>(unitNos);
		List<String> deduplicatedList = new ArrayList<>(set);
		for(int i=0;i<deduplicatedList.size();i++){
			AccessDeviceInfo accessDeviceInfo  = accessDeviceInfoService.detail(deduplicatedList.get(i));
			head = head+accessDeviceInfo.getDeviceName()+",";
		}
		if (head.endsWith(",")) {
			head = head.substring(0, head.length() - 1);
		}
		body = head+body;
		AlarmTypeConf alarmTypeConf1 =	alarmTypeConfService.getTypeByCode(alarmId);
		if(alarmTypeConf1.getWay().contains("sms")){
			for(int i=0;i<alarmTypeConf1.getSenderList().length;i++){
				UserVO userVO  = userService.selectUserVoById(Long.valueOf(alarmTypeConf1.getSenderList()[i]));
				if(ObjectUtil.isNotEmpty(userVO.getEmail())){
					sender.sendMsg(userVO.getEmail(),body);
				}
			}
		}
	}

	private JSONArray getJson(String unitNo) {
		AccessDeviceInfo accessDeviceInfo = accessDeviceInfoService.detail(unitNo);
		AccessThingModel accessThingModel = accessThingModelService.getThingModelByProductKey(accessDeviceInfo.getProductKey());
		JSONObject json = accessThingModel.getModel();
		JSONArray jsonArray = (JSONArray) json.get("properties");
		return jsonArray;
	}

	private boolean getBoolean(Object obj, SceneExecuteConditions sceneExecuteCondition, Map map) {
		if ("int32".equals(obj)) {
			Integer nowValue = Integer.valueOf(map.get(sceneExecuteCondition.getChannelNo()) + "");
			//0-> 1-< 2-= 3-范围值
			if (sceneExecuteCondition.getConfigType() != 3) {
				Integer fixedValue = Integer.valueOf(sceneExecuteCondition.getFixedValue() + "");
				if (sceneExecuteCondition.getConfigType() == 0) {
					if (nowValue.compareTo(fixedValue) > 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 1) {
					if (nowValue.compareTo(fixedValue) < 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 2) {
					if (nowValue.compareTo(fixedValue) == 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 4) {
					if (fixedValue >= nowValue) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 5) {
					if (nowValue <= fixedValue) {
						return true;
					}
				}
			} else {
				Integer leftValue = Integer.valueOf(sceneExecuteCondition.getLowerValue());
				Integer rightValue = Integer.valueOf(sceneExecuteCondition.getUpperValue());
				if (sceneExecuteCondition.getConfigType() == 3) {
					if (leftValue.compareTo(nowValue) < 0 && rightValue.compareTo(nowValue) > 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 6) {
					if (nowValue < leftValue && nowValue > rightValue) {
						return true;
					}
				}
			}
		} else if ("float".equals(obj)) {
			Float nowValue = Float.valueOf(map.get(sceneExecuteCondition.getChannelNo()) + "");
			//0-> 1-< 2-= 3-范围值
			if (sceneExecuteCondition.getConfigType() != 3) {
				Float fixedValue = Float.valueOf(sceneExecuteCondition.getFixedValue() + "");
				if (sceneExecuteCondition.getConfigType() == 0) {
					if (nowValue.compareTo(fixedValue) > 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 1) {
					if (nowValue.compareTo(fixedValue) < 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 2) {
					if (nowValue.compareTo(fixedValue) == 0) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 4) {
					if (fixedValue >= nowValue) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 5) {
					if (nowValue <= fixedValue) {
						return true;
					}
				}
			} else {
				Float leftValue = Float.valueOf(sceneExecuteCondition.getLowerValue());
				Float rightValue = Float.valueOf(sceneExecuteCondition.getUpperValue());
				if (sceneExecuteCondition.getConfigType() == 3) {
					if (leftValue < nowValue && rightValue > nowValue) {
						return true;
					}
				} else if (sceneExecuteCondition.getConfigType() == 6) {
					if (nowValue < leftValue && nowValue > rightValue) {
						return true;
					}
				}
			}
		}
		return false;
	}
}
